/**
 * @class 控制器父类
 * @author DuskyHuang 圣子
 * @description 隔离业务逻辑与系统（C）
*/

import { _decorator, Component, director, Scene, } from 'cc';
import { Notifications } from '../../configs';
import { notifier, controllers, bridge, inner } from '../boot';
const { SECOND, SPAN } = Notifications.Time;
const { ccclass } = _decorator;

@ccclass('cfw.Controller')
export default abstract class Controller extends Component {

    /**
      * 是否监听每秒回调
      * @description 设置为true时onSecond每秒触发
     */
    protected get listenSecond(): boolean {
        return inner.hasHandler(this.onSecond, this);
    }
    protected set listenSecond(arg: boolean) {
        if (arg && !this.listenSecond) inner.attach(SECOND, this.onSecond, this);
        else if (!arg && this.listenSecond) inner.detach(SECOND, this.onSecond, this);
    }

    /**
      * 是否监听每时段回调
      * @description 设置为true时onSpan每时间段触发
      * @explain 时段长短的设置：TimerSystem.span = num
     */
    protected get listenSpan(): boolean {
        return inner.hasHandler(this.onSecond, this);
    }
    protected set listenSpan(arg: boolean) {
        if (arg && !this.listenSpan) inner.attach(SPAN, this.onSpan, this);
        else if (!arg && this.listenSpan) inner.detach(SPAN, this.onSpan, this);
    }

    protected __preload(): void {
        if (isFunc(super.__preload)) super.__preload();
        controllers.unshiftUnique(this);
    }

    protected on(type: any, handler: Handler, priority: number = 0): void {
        notifier.attach(type, handler, this, false, priority);
    }

    protected once(type: any, handler: Handler, priority: number = 0): void {
        notifier.attach(type, handler, this, true, priority);
    }

    protected off(type: any, handler: Handler): void {
        notifier.detach(type, handler, this);
    }

    protected notify(type: any, ...args: any[]): void {
        notifier.dispatch(type, ...args);
    }

    protected onDestroy(): void {
        notifier.unload(this);
        bridge.unload(this);
        controllers.remove(this);
    }

    protected onSecond(dt?: time.sec, sec?: number): void { }

    protected onSpan(dt?: time.sec, span?: number): void { }

    /**
      * 当前场景
     */
    protected get scene(): Scene { return director.getScene(); }
}